home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 343_02 / filter.c < prev    next >
C/C++ Source or Header  |  1992-04-11  |  11KB  |  444 lines

  1.  
  2.        /***********************************************
  3.        *
  4.        *       file d:\cips\filter.c
  5.        *
  6.        *       Functions: This file contains
  7.        *          filter_image
  8.        *          median_filter
  9.        *          setup_fitlers
  10.        *          get_filter_options
  11.        *          median_of
  12.        *          sort_elements
  13.        *          swap
  14.        *
  15.        *       Purpose:
  16.        *          These functions implement several
  17.        *          types of basic spatial frequency filters.
  18.        *
  19.        *       External Calls:
  20.        *          wtiff.c - does_not_exist
  21.        *                    round_off_image_size
  22.        *                    create_allocate_tiff_file
  23.        *                    write_array_into_tiff_image
  24.        *          tiff.c - read_tiff_header
  25.        *          rtiff.c - read_tiff_image
  26.        *          numcvrt.c - get_integer
  27.        *
  28.        *
  29.        *       Modifications:
  30.        *          15 February 1992 - created
  31.        *
  32.        *************************************************/
  33.  
  34. #include "d:\cips\cips.h"
  35. #include <malloc.h>
  36.  
  37.  
  38.      /*******************************************
  39.      *
  40.      *   Define the filter masks.
  41.      *
  42.      *******************************************/
  43.  
  44. short lpf_filter_6[3][3] =
  45.    { {0, 1, 0},
  46.      {1, 2, 1},
  47.      {0, 1, 0}};
  48.  
  49. short lpf_filter_9[3][3] =
  50.    { {1, 1, 1},
  51.      {1, 1, 1},
  52.      {1, 1, 1}};
  53.  
  54. short lpf_filter_10[3][3] =
  55.    { {1, 1, 1},
  56.      {1, 2, 1},
  57.      {1, 1, 1}};
  58.  
  59. short lpf_filter_16[3][3] =
  60.    { {1, 2, 1},
  61.      {2, 4, 2},
  62.      {1, 2, 1}};
  63.  
  64. short hpf_filter_1[3][3] =
  65.    { { 0, -1,  0},
  66.      {-1,  5, -1},
  67.      { 0, -1,  0}};
  68.  
  69. short hpf_filter_2[3][3] =
  70.    { {-1, -1, -1},
  71.      {-1,  9, -1},
  72.      {-1, -1, -1}};
  73.  
  74. short hpf_filter_3[3][3] =
  75.    { { 1, -2,  1},
  76.      {-2,  5, -2},
  77.      { 1, -2,  1}};
  78.  
  79.  
  80.  
  81.  
  82.  
  83.      /*******************************************
  84.      *
  85.      *   filter_image(...
  86.      *
  87.      *   This function filters an image by using
  88.      *   a single 3x3 mask.
  89.      *
  90.      *******************************************/
  91.  
  92.  
  93. filter_image(in_name, out_name, the_image, out_image,
  94.              il, ie, ll, le, filter, type)
  95.    char   in_name[], out_name[];
  96.    int    il, ie, ll, le, type;
  97.    short  filter[3][3],
  98.           the_image[ROWS][COLS],
  99.           out_image[ROWS][COLS];
  100.  
  101. {
  102.    int    a, b, d, i, j, k,
  103.           length, max, sum, width;
  104.    struct tiff_header_struct image_header;
  105.  
  106.  
  107.    if(does_not_exist(out_name)){
  108.       printf("\n\n output file does not exist %s", out_name);
  109.       read_tiff_header(in_name, &image_header);
  110.       round_off_image_size(&image_header,
  111.                            &length, &width);
  112.       image_header.image_length = length*ROWS;
  113.       image_header.image_width  = width*COLS;
  114.       create_allocate_tiff_file(out_name, &image_header,
  115.                                 out_image);
  116.    }  /* ends if does_not_exist */
  117.  
  118.    read_tiff_header(in_name, &image_header);
  119.  
  120.    d = type;
  121.    if(type == 2 || type == 3) d = 1;
  122.  
  123.    max = 255;
  124.    if(image_header.bits_per_pixel == 4)
  125.       max = 16;
  126.  
  127.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  128.  
  129.          /* Do convolution over image array */
  130.    printf("\n");
  131.    for(i=1; i<ROWS-1; i++){
  132.       if( (i%10) == 0) printf("%d ", i);
  133.       for(j=1; j<COLS-1; j++){
  134.          sum = 0;
  135.          for(a=-1; a<2; a++){
  136.             for(b=-1; b<2; b++){
  137.                sum = sum +
  138.                      the_image[i+a][j+b] *
  139.                      filter[a+1][b+1];
  140.             }
  141.          }
  142.          sum               = sum/d;
  143.          if(sum < 0)   sum = 0;
  144.          if(sum > max) sum = max;
  145.          out_image[i][j]   = sum;
  146.  
  147.       }  /* ends loop over j */
  148.    }  /* ends loop over i */
  149.  
  150.    fix_edges(out_image, 1);
  151.  
  152.    write_array_into_tiff_image(out_name, out_image,
  153.                                il, ie, ll, le);
  154.  
  155. }  /* ends filter_image */
  156.  
  157.  
  158.  
  159.  
  160.      /*******************************************
  161.      *
  162.      *   median_filter(..
  163.      *
  164.      *   This function performs a median filter
  165.      *   on an image using a size (3x3, 5x5, etc.)
  166.      *   specified in the call.
  167.      *
  168.      *******************************************/
  169.  
  170.  
  171. median_filter(in_name, out_name, the_image, out_image,
  172.               il, ie, ll, le, size)
  173.    char   in_name[], out_name[];
  174.    int    il, ie, ll, le, size;
  175.    short  the_image[ROWS][COLS],
  176.           out_image[ROWS][COLS];
  177.  
  178. {
  179.    int    a, b, count, i, j, k,
  180.           length, sd2, sd2p1, ss, width;
  181.    short  *elements;
  182.    struct tiff_header_struct image_header;
  183.  
  184.    sd2   = size/2;
  185.    sd2p1 = sd2 + 1;
  186.  
  187.       /**********************************************
  188.       *
  189.       *   Allocate the elements array large enough
  190.       *   to hold size*size shorts. 
  191.       *
  192.       **********************************************/
  193.  
  194.    ss       = size*size;
  195.    elements = (short *) malloc(ss * sizeof(short));
  196.  
  197.    if(does_not_exist(out_name)){
  198.       printf("\n\n output file does not exist %s", out_name);
  199.       read_tiff_header(in_name, &image_header);
  200.       round_off_image_size(&image_header,
  201.                            &length, &width);
  202.       image_header.image_length = length*ROWS;
  203.       image_header.image_width  = width*COLS;
  204.       create_allocate_tiff_file(out_name, &image_header,
  205.                                 out_image);
  206.    }  /* ends if does_not_exist */
  207.  
  208.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  209.  
  210.       /***************************
  211.       *
  212.       *   Loop over image array
  213.       *
  214.       ****************************/
  215.  
  216.    printf("\n");
  217.    for(i=sd2; i<ROWS-sd2; i++){
  218.       if( (i%10) == 0) printf("%d ", i);
  219.       for(j=sd2; j<COLS-sd2; j++){
  220.          count = 0;
  221.          for(a=-sd2; a<sd2p1; a++){
  222.             for(b=-sd2; b<sd2p1; b++){
  223.                elements[count] = the_image[i+a][j+b];
  224.                count++;
  225.             }
  226.          }
  227.          out_image[i][j] = median_of(elements, &ss);
  228.       }  /* ends loop over j */
  229.    }  /* ends loop over i */
  230.  
  231.    fix_edges(out_image, sd2);
  232.  
  233.    write_array_into_tiff_image(out_name, out_image,
  234.                                il, ie, ll, le);
  235.  
  236.    free(elements);
  237.  
  238. }  /* ends median_filter */
  239.  
  240.  
  241.  
  242.    /***********************************************
  243.     *
  244.     *    median_of(...
  245.     *
  246.     *    This function finds and returns the
  247.     *    median value of the elements array.
  248.     *
  249.     *    As a side result, it also sorts the
  250.     *    elements array.
  251.     *
  252.     ***********************************************/
  253.  
  254. median_of(elements, count)
  255.    int   *count;
  256.    short elements[];
  257. {
  258.    short median;
  259.  
  260.    sort_elements(elements, count);
  261.    median = elements[*count/2];
  262.    return(median);
  263. }  /* ends median_of */
  264.  
  265.  
  266.  
  267.    /***********************************************
  268.     *
  269.     *    sort_elements(...
  270.     *
  271.     *    This function performs a simple bubble
  272.     *    sort on the elements from the median
  273.     *    filter.
  274.     *
  275.     ***********************************************/
  276.  
  277. sort_elements(elements, count)
  278.    int   *count;
  279.    short elements[];
  280. {
  281.    int i, j;
  282.    j = *count;
  283.    while(j-- > 1){
  284.       for(i=0; i<j; i++){
  285.          if(elements[i] > elements[i+1])
  286.             swap(&elements[i], &elements[i+1]);
  287.       }
  288.    }
  289. }  /* ends sort_elements */
  290.  
  291.  
  292.  
  293.    /***********************************************
  294.     *
  295.     *    swap(...
  296.     *
  297.     *    This function swaps two shorts.
  298.     *
  299.     ***********************************************/
  300.  
  301. swap(a, b)
  302.    short *a, *b;
  303. {
  304.    short temp;
  305.    temp  = *a;
  306.    *a    = *b;
  307.    *b    = temp;
  308. }  /* ends swap */
  309.  
  310.  
  311.  
  312.    /*******************************************************
  313.     *
  314.     *    setup_filters(...
  315.     *
  316.     *    This function copies the filter mask values defined
  317.     *    at the top of this file into the filter array.
  318.     *
  319.     *******************************************************/
  320.  
  321.  
  322. setup_filters(filter_type, low_high, filter)
  323.    char   low_high[];
  324.    int    filter_type;
  325.    short  filter[3][3];
  326. {
  327.    int i, j;
  328.  
  329.    if(low_high[0] == 'l'  || low_high[